-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose accessors for private/public key on elliptic curve keys #259
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple tiny nits.
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #259 +/- ##
==========================================
+ Coverage 95.42% 95.47% +0.05%
==========================================
Files 51 52 +1
Lines 6733 6921 +188
==========================================
+ Hits 6425 6608 +183
- Misses 308 313 +5 ☔ View full report in Codecov by Sentry. |
aws-lc-rs/src/ec.rs
Outdated
PublicKey(pubkey_box) | ||
/// Provides the public key as a DER-encoded `SubjectPublicKeyInfo` structure. | ||
#[must_use] | ||
pub fn as_der(&self) -> Buffer<'_, EcPublicKeyDer> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm really not to fond of how we are using the names as_der
and EcPublicKeyDer
to mean "write the output as DER following the X.509 ASN.1 SubjectPublicKeyInfo
type definition". DER is an ASN.1 encoding scheme, SubjectPublicKeyInfo
is the structure to describe a public key that could be encoded in various formats, PEM, DER, BER, etc. I feel like we should be more explicit for own benefit in case we need to serialize to different structure types in the future.
Case in point, you could have a function that just writes the raw key bytes as a DER encode OCTET STRING. That's valid DER, but not a SubjectPublicKeyInfo.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would as_x509
and X509PublicKey
any better?
As a reference, in the BC-FIPS
Java world, the import of the der bytes (after base64 decoding if any) is something like:
new X509EncodedKeySpec(bytes)
aws-lc-rs/src/ec/key_pair.rs
Outdated
/// | ||
/// # Errors | ||
/// `error::Unspecified` if serialization failed. | ||
pub fn to_der(&self) -> Result<Buffer<'static, EcPrivateKeyDer>, Unspecified> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wanted to highlight this as another example of ambiguity around meaning of to to_der
. EcsdaPrivateKey encode to DER but follow PKCS#8 (v1 or v2) and is explicit with the functions. In this case though to_der
is serializing only to the specific PrivateKey
format, specifically from RFC 5915. This is the same structure that is wrapped by PKCS#8 structure! Now you could argue that KeyPair type makes sense to use PKCS#8 cause that supports both being present (V2). But it also supports serializing just the private key, so why does to_der
here not use that? Basically I think the intent needs to be more clear for the serialization functions. I'm not saying we shouldn't support these types, but don't want to overload the term DER. ASN.1 is already confusing enough :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with your concerns. I'm still thinking about what changes need to be made regarding them.
Here are a few thoughts I have about what's important regarding the serialization/deserialization methods we provide for our structs:
- Documentation should be unambiguous about the encoding(s) provided or required.
- Method names should be clear about their purpose, but don't need to indicate details of the encoding.
- Method names should be consistent/symmetric within a given struct. For example, the encoding serialized by a
to_der
function should be appropriate for afrom_der
to deserialize the same struct (if such a method exists). - Structs/Types (e.g.,
EcPrivateKeyDer
) should be unambiguous and guide users toward proper usage of serialized data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My latest commit adds/improves the documentation so that the encoding provided by serialization methods is more clear. I also moved the structs that differentiate buffer types to a signature::encoding
module. We might also rename the (e.g.) to_der
methods to more directly indicate the type of encoding provided, but I'm not yet sure that's needed.
This is a one-way-door API decision, so it should be carefully considered.
9ed166e
to
db45cd0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some minor feedback and one question, otherwise this looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of always marshaling a public key eagerly into both octet string and x509 formats, would it make more sense to have an API that allows either format to be lazily retrieved instead?
I can imagine cases where only one format is needed but not the other.
Also adds test coverage for EcdsaKeyPair::from_private_key_der and EcdsaPrivateKey::to_der (round trip test).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully my final comment :)
pub struct PublicKey(Box<[u8]>); | ||
pub struct PublicKey { | ||
algorithm: &'static EcdsaSigningAlgorithm, | ||
octets: Box<[u8]>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a general question: We were doing this previously as well, so its not a blocker. We allocate the public key with a maximum length on the stack in marshal_public_key
, does octets
have to be a Box
here?
@@ -103,6 +103,7 @@ extern crate core; | |||
|
|||
pub mod aead; | |||
pub mod agreement; | |||
mod buffer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor nit: Noticed this when checking if Buffer
was a new public interface, should we move buffer
down to list of other non-public modules below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have another PR ready after this. I'll update the order there.
👏 |
A rebase of #234 onto the latest on main.
Description of changes:
Call-outs:
to_pkcs8v1
versusto_pkcs8
. Perhaps we need both?(From #234)
Testing:
(From #234)
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.